﻿using System.Threading;
using Cysharp.Threading.Tasks;
using DG.Tweening;
using IQIGame.Onigao.Framework;
using UnityEngine;

namespace IQIGame.Onigao.GamePlay
{
    public class StoryAction_Shake : StoryAction
    {
        private float _duration;
        private Vector3 _shakeRange;
        private int _speed;

        private Vector3 _oldPos;
        private Tweener _tween;

        protected override bool OnInitialize(GameObject root, StoryActionData data)
        {
            base.OnInitialize(root, data);
            if (data is StoryActionData_Shake rShake)
            {
                this._duration = rShake.duration;
                this._shakeRange = new Vector3(rShake.range.x, rShake.range.y, 0);
                this._speed = rShake.speed;
                return true;
            }
            return false;
        }

        protected override async UniTask OnStart(CancellationToken cancel)
        {
            await base.OnStart(cancel);
            var fDuration = this._duration > 0 ? this._duration : int.MaxValue;
            this._oldPos = this.root.transform.localPosition;
            this._tween = DOTween.Shake(() =>
                {
                    if (this.root)
                    {
                        return this.root.transform.localPosition;
                    }
                    return Vector3.zero;
                },
                x =>
                {
                    if (this.root)
                    {
                        this.root.transform.localPosition = x;
                    }
                },
                fDuration,
                this._shakeRange,
                this._speed, 90, false, ShakeRandomnessMode.Full);

            if (this._duration > 0)
            {
                await this._tween.PlayAsync(cancel);
                this._tween = null;
            }
            else
            {
                // this._tween.SetLoops(-1);
#if UNITY_EDITOR
                if (!Application.isPlaying)
                {
                    this._tween.StartPreview();
                }
#endif
            }
        }

        protected override async UniTask OnEnd(CancellationToken cancel)
        {
            await base.OnEnd(cancel);
#if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                DoTweenUtil.StopPreview();
            }
#endif
            if (this._tween != null)
            {
                this.root.transform.localPosition = this._oldPos;
                this._tween.Kill();
            }
            this._tween = null;
        }

        protected override void OnDispose()
        {
            base.OnDispose();
#if UNITY_EDITOR
            if (!Application.isPlaying)
            {
                DoTweenUtil.StopPreview();
            }
#endif
            if (this._tween != null)
            {
                this.root.transform.localPosition = this._oldPos;
                this._tween.Kill();
            }
            this._tween = null;
        }

        public override void OnReset()
        {
            base.OnReset();
            this._duration = 0;
            this._shakeRange = default;
            this._speed = 0;
            this._tween = null;
            this._oldPos = default;
        }

        public override void Free()
        {
            ClassPool.Put(this);
        }
    }
}